package cn.iocoder.yudao.module.promotion.service.prizedraw;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectKit;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
import cn.iocoder.yudao.module.promotion.controller.admin.prizedraw.vo.*;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawSettingBatchDO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.prizedraw.PrizeDrawSettingProductDO;
import cn.iocoder.yudao.module.promotion.dal.mysql.prizedraw.PrizeDrawSettingBatchMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;

/**
 * 抽奖设置商品批次 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class PrizeDrawSettingBatchServiceImpl extends ServiceImpl<PrizeDrawSettingBatchMapper, PrizeDrawSettingBatchDO> implements PrizeDrawSettingBatchService {

    @Resource
    private PrizeDrawSettingBatchMapper prizeDrawSettingBatchMapper;
    @Resource
    private PrizeDrawSettingProductService PrizeDrawSettingProductService;
    @Resource
    private MemberUserMapper memberUserMapper;

    /**
     * 分页查询
     *
     * @param dto 查询条件
     * @return 分页结果
     */
    @Override
    public PageResult<PrizeDrawSettingBatchRespVO> paging(PrizeDrawSettingBatchPageReqVO dto) {
        PageResult<PrizeDrawSettingBatchRespVO> paging = baseMapper.paging(dto);
        List<PrizeDrawSettingBatchRespVO> records = paging.getList();
        if (CollUtil.isNotEmpty(records)) {
            List<Long> syIds = shuyinProducts(CollectKit.map(records, PrizeDrawSettingBatchRespVO::getPrizeDrawSettingBatchId));

            Map<Long, MemberUserDO> updateByMap =new HashMap<>();
            List<Long> updateBys = CollectKit.map(records, PrizeDrawSettingBatchRespVO::getUpdater);
            updateBys = CollUtil.distinct(updateBys);
            List<MemberUserDO> updateByLust = memberUserMapper.selectList(new LambdaQueryWrapper<MemberUserDO>().in(MemberUserDO::getId, updateBys));
            if (CollUtil.isNotEmpty(updateByLust)){
                updateByMap=updateByLust.stream().collect(Collectors.toMap(MemberUserDO::getId, Function.identity()));
            }
            if (Objects.nonNull(updateByMap) && CollUtil.isNotEmpty(updateByMap)) {
                for (PrizeDrawSettingBatchRespVO record : records) {
                    MemberUserDO sysBaseUserDto = updateByMap.get(record.getUpdater());
                    if (Objects.nonNull(sysBaseUserDto)) {
                        record.setUpdateByName(sysBaseUserDto.getNickname());
                    }
                    List<PrizeDrawSettingProductRespVO> productsByBatchId = PrizeDrawSettingProductService.getProductsByBatchId(record.getPrizeDrawSettingBatchId());
                    List<Long> fsyIds = CollUtil.isEmpty(syIds) ? ListUtil.list(false, -1L) : syIds;
                    productsByBatchId.removeIf(product -> !fsyIds.contains(product.getSkuId()));

                    if (CollUtil.isNotEmpty(productsByBatchId)) {
                        record.setProductIds(CollectKit.map(productsByBatchId, PrizeDrawSettingProductRespVO::getSkuId));
                    }
                    record.setProdNums(productsByBatchId.size());
                }
            }
        }
        return paging;
    }

    /**
     * 根据ID获取信息
     *
     * @param id 主键
     * @return 信息
     */
    @Override
    public PrizeDrawSettingBatchRespVO getInfoById(Long id) {
        PrizeDrawSettingBatchRespVO record = baseMapper.single(id);
        if (Objects.nonNull(record)) {
            MemberUserDO updateBy = memberUserMapper.selectById(record.getUpdater());
            if (ObjectUtil.isNotNull(updateBy)) {
                record.setUpdateByName(updateBy.getNickname());
            }
            List<Long> syIds = shuyinProducts(ListUtil.list(false, record.getPrizeDrawSettingBatchId()));
            record.setProductIds(syIds);
            record.setProdNums(syIds.size());
        } else {
            throw exception(new ErrorCode(500, "抽奖设置商品批次详情信息不存在"));
        }
        return record;
    }

    /**
     * 商品批量查询
     *
     * @param batchIds 批次ID
     * @return
     */
    @Override
    public List<Long> shuyinProducts(List<Long> batchIds) {
        List<Long> productIds = PrizeDrawSettingProductService.getProductsByBatchIds(batchIds);
        return productIds;
    }

    /**
     * 保存
     *
     * @param dto 抽奖设置商品批次信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void preserve(PrizeDrawSettingBatchDto dto) {
        PrizeDrawSettingBatchDO batch = BeanUtil.copyProperties(dto, PrizeDrawSettingBatchDO.class);

        Long intersection = baseMapper.intersection(batch);
        if (intersection > 0) {
            throw exception(new ErrorCode(500, "批次时间不允许存在交集"));
        }

        LambdaQueryWrapper<PrizeDrawSettingBatchDO> mpdsbq = new LambdaQueryWrapper<>();
        mpdsbq.eq(PrizeDrawSettingBatchDO::getBatchName, batch.getBatchName());
        PrizeDrawSettingBatchDO ori = getOne(mpdsbq, false);

        if (Objects.isNull(batch.getPrizeDrawSettingBatchId())) {
            if (Objects.nonNull(ori)) {
                throw exception(new ErrorCode(500, "批次名称已存在"));
            }

            save(batch);
        } else {
            if (Objects.nonNull(ori) && !ori.getPrizeDrawSettingBatchId().equals(batch.getPrizeDrawSettingBatchId())) {
                throw exception(new ErrorCode(500, "批次名称已存在"));
            }
            updateById(batch);
        }

        LambdaQueryWrapper<PrizeDrawSettingProductDO> mpdspu = new LambdaQueryWrapper<>();
        mpdspu.eq(PrizeDrawSettingProductDO::getPrizeDrawSettingBatchId, batch.getPrizeDrawSettingBatchId());
        PrizeDrawSettingProductService.remove(mpdspu);

        List<PrizeDrawSettingProductDO> products = ListUtil.list(false);
        List<Long> productIds = dto.getProductIds();
        for (Long productId : productIds) {
            PrizeDrawSettingProductDO product = new PrizeDrawSettingProductDO();
            product.setPrizeDrawSettingBatchId(batch.getPrizeDrawSettingBatchId());
            product.setSkuId(productId);

            products.add(product);
        }

        PrizeDrawSettingProductService.saveBatch(products);
    }

    /**
     * 启停
     *
     * @param dto 抽奖设置商品批次信息
     */
    @Override
    public void updown(PrizeDrawSettingBatchUpdownDto dto) {
        Integer updown = dto.getUpdown();
        List<Long> prizeDrawSettingBatchIds = dto.getPrizeDrawSettingBatchIds();

        for (Long prizeDrawSettingBatchId : prizeDrawSettingBatchIds) {
            if (Integer.valueOf(1).equals(updown)) {
                PrizeDrawSettingBatchDO batch = getById(prizeDrawSettingBatchId);
                PrizeDrawSettingBatchRespVO intersection = baseMapper.intersectionVo(batch);
                if (Objects.nonNull(intersection)) {
                    throw exception(new ErrorCode(1111, "批次[" + batch.getBatchName() + "]与启用批次[" + intersection.getBatchName() + "]，时间上存在交集不能启用"));
                }
            }
        }

        LambdaUpdateWrapper<PrizeDrawSettingBatchDO> mpdsbu = new LambdaUpdateWrapper<>();
        mpdsbu.in(PrizeDrawSettingBatchDO::getPrizeDrawSettingBatchId, prizeDrawSettingBatchIds);
        mpdsbu.set(PrizeDrawSettingBatchDO::getUpdown, updown);
        update(mpdsbu);
    }

    /**
     * 删除
     *
     * @param dto 抽奖设置商品批次信息
     */
    @Override
    public void delete(PrizeDrawSettingBatchDeleteDto dto) {
        removeById(dto.getPrizeDrawSettingBatchId());
    }

}